package com.me.study.concurrent.threadUtil;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * CyclicBarrier（同步屏障）测试类
 *
 * @author ME
 * @date   2019/6/4
 */
public class TestCyclicBarrier {

    public static void main(String[] args) {
        TestCyclicBarrier demo =  new TestCyclicBarrier();
        CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new Runnable() {
            @Override
            public void run() {
                System.out.println("[直接调用] 执行回调函数: " + Thread.currentThread().getName());
            }
        });
        demo.process(cyclicBarrier);
        System.out.println("[直接调用] 主线程名是: "+ Thread.currentThread().getName());
    }

    private void process(CyclicBarrier cyclicBarrier) {
        final int n = 3;
        Runnable worker = new Runnable() {
            @Override
            public void run() {
                System.out.println("start work");
                for (int i = 0; i < n; i++) {
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                    try {
                        // 返回的就是当前线程到达约定点（barrier）的下标：第一个到达是0，第二个--1，第三个--2
                        // TODO 同一线程，多次 await 只有第一次生效，后续直接返回到达时的下标
                        int arrival_index = cyclicBarrier.await();
                        if (0 == arrival_index) {
                            System.out.println("第一个到达的线程需要工作更久, so 再此迭代: " + Thread.currentThread().getName());
                        }
                    } catch (BrokenBarrierException | InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }

                System.out.println("\n工作完成, 工作线程是: " + Thread.currentThread().getName());
            }
        };

        Thread t1 = new Thread(worker, "myWoke1");
        Thread t2 = new Thread(worker, "myWoke2");
        t1.start();
        t2.start();
    }


    // public void showInfThreadWhenDirectly() {
    //     CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new Runnable() {
    //         @Override
    //         public void run() {
    //             Thread.currentThread().setDisplayName("Thread-Callback");
    //             System.out.println("[直接调用] 执行回调函数: " + Thread.currentThread().getDisplayName());
    //         }
    //     });
    //     process(cyclicBarrier);
    //     System.out.println("[直接调用] 主线程名是: "+ Thread.currentThread().getDisplayName());
    // }

}
